package br.pesquisa.lsystem.gui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

import br.pesquisa.lsystem.Celula;
import br.pesquisa.lsystem.Interpretador;

@SuppressWarnings("serial")
public class MainFrame extends JInternalFrame {

	private Interpretador<Celula> interpretador;
	private List<Celula> celulas;

	private JTextField textAxioma;
	private JButton buttonAdicionar;
	private JComboBox comboAlfabeto;
	private JButton buttonLimpar;
	private CellPanel cellPanel;
	private JButton startButton;

	public MainFrame() {
		super("L-System");
	}

	public CellPanel getCellPanel() {
		return cellPanel;
	}

	public void setCellPanel(CellPanel cellPanel) {
		this.cellPanel = cellPanel;
	}

	public Interpretador<Celula> getInterpretador() {
		return interpretador;
	}

	public void setInterpretador(Interpretador<Celula> interpretador) {
		this.interpretador = interpretador;
	}

	public JButton getButtonAdicionar() {
		return buttonAdicionar;
	}

	public void setButtonAdicionar(JButton buttonAdicionar) {
		this.buttonAdicionar = buttonAdicionar;
	}

	public JButton getButtonLimpar() {
		return buttonLimpar;
	}

	public void setButtonLimpar(JButton buttonLimpar) {
		this.buttonLimpar = buttonLimpar;
	}

	public JButton getStartButton() {
		return startButton;
	}

	public void setStartButton(JButton startButton) {
		this.startButton = startButton;
	}

	public void init() {
		textAxioma = new JTextField(25);
		textAxioma.setEditable(false);
		atualizarAxioma(textAxioma);

		comboAlfabeto = new JComboBox();
		celulas = new ArrayList<Celula>();
		atualizarAlfabeto();

		buttonAdicionar = new JButton("<<");
		buttonAdicionar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				interpretador.getGramatica().getAxioma().add(celulas.get(
						comboAlfabeto.getSelectedIndex()));
				atualizarAxioma(textAxioma);
			}
		});

		buttonLimpar = new JButton("Limpar");
		buttonLimpar.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				interpretador.getGramatica().getAxioma().clear();
				atualizarAxioma(textAxioma);
			}
		});

		JPanel topPanel = new JPanel();
		topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
		topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		topPanel.add(new JLabel("Axioma: "));
		topPanel.add(textAxioma);
		topPanel.add(buttonAdicionar);
		topPanel.add(comboAlfabeto);
		topPanel.add(buttonLimpar);

		setCellPanel(new ProcessingCellPanel(this));
		getCellPanel().init();
		getInterpretador().addObserver(getCellPanel());

		JPanel centerPanel = new JPanel();
		centerPanel.setLayout(new BoxLayout(centerPanel, BoxLayout.PAGE_AXIS));
		centerPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		centerPanel.add(getCellPanel(), BorderLayout.CENTER);

		startButton = new JButton("Iniciar");
		startButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				interpretador.setEstado(new LinkedList<Celula>());
				interpretador.getEstado().addAll(
						interpretador.getGramatica().getAxioma());
				cellPanel.setMaxElementos(0);
				cellPanel.getEstados().clear();
				cellPanel.getEstados().add(interpretador.getEstado());
				cellPanel.setMaxElementos(interpretador.getEstado().size());
				cellPanel.repaint();

				Thread thread = new Thread(interpretador);
				thread.start();
				startButton.setEnabled(false);
				buttonAdicionar.setEnabled(false);
				buttonLimpar.setEnabled(false);
			}
		});
		JPanel buttonPanel = new JPanel();
		buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
		buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
		buttonPanel.add(Box.createHorizontalGlue());
		buttonPanel.add(startButton);

		add(topPanel, BorderLayout.NORTH);
		add(centerPanel, BorderLayout.CENTER);
		add(buttonPanel, BorderLayout.SOUTH);

		setVisible(true);
	}

	private void atualizarAxioma(JTextField text) {
		StringBuilder axioma = new StringBuilder();
		for(Celula celula: interpretador.getGramatica().getAxioma()) {
			axioma.append(celula.getLetra());
			if(celula.getSentido() != null) {
				axioma.append(" - ").append(celula.getSentido());
			}
			axioma.append(", ");
		}
		if(axioma.length() > 0) {
			axioma.setLength(axioma.length() - 2);
		}

		text.setText(axioma.toString());
	}

	public void atualizarAlfabeto() {
		comboAlfabeto.removeAllItems();
		celulas.clear();

		for(Celula celula: getInterpretador().getGramatica().getAlfabeto()
				.getElementos()) {
			comboAlfabeto.addItem(celula.getLetra() + (celula.getSentido() == null?
					"": " - " + celula.getSentido()));
			celulas.add(celula);
		}
	}
}
